import numpy as np
from gm.api import *
import os
from MSCI_tools import msci_tools as tools

from MSCI_高增长 import 低PB价值投资策略 as my_own_fun
import csv
def init(context):
    schedule(schedule_func=algo, date_rule='1d', time_rule='09:31:00')

    context.index = "SHSE.000001"
    context.count = 55
    context.black_day_count = 0
    context.can_trade = True
    context.black_list = []
    context.symbol_high = {}
    context.num = 5 #每次的持股数
    context.record_file = "../MSCI_tools/多因子策略存档回测.csv"

def algo(context):
    now = context.now
    last_day = get_previous_trading_date("SHSE", now)

    market_data = history_n(symbol=context.index, frequency="1d", count=context.count, end_time=now,
                            fields="open,high,low,close", fill_missing="last", df=True)
    market_close = market_data["close"].values
    market_open = market_data["open"].values
    market_low = market_data["low"].values
    marker_mean = np.mean(market_close[:-1])
    marker_min_low = np.min(market_low[:-1])

    #这里是设置清仓条件
    if market_open[-1] < marker_mean:
        order_close_all()
        context.black_day_count = 0
        context.can_trade = False
        context.symbol_high = {}
        context.symbol_low = {}

    #这里是设置清仓后多少天不要交易
    else:
        context.black_day_count += 1
        if context.black_day_count >= 3:
            context.can_trade = True


    if context.can_trade:
        #确认下最高价，回撤多少就清仓，然后注入黑名单
        positions = context.account().positions()
        for position in positions:
            symbol = position['symbol']
            data = history_n(symbol,frequency="1d",count=1,end_time=last_day,fields="high,low",df=True)
            high = data["high"].values
            context.symbol_high[symbol] = np.max([high[0],context.symbol_high[symbol]])

            low = data["low"].values
            context.symbol_low[symbol] = np.min([low[0],context.symbol_low[symbol]])


        #根据来源对,获取symbol_list
        target_index = "SZSE.399672"
        symbol_list = tools.get_symbol_list(index=target_index,now=now)

        context.target_index = target_index
        # 这里设置一些基础的过滤条件

        # PETTM > 0
        df = get_fundamentals(table='trading_derivative_indicator', symbols=symbol_list, start_date=last_day,
                              end_date=last_day, fields="PETTM", filter="PETTM > 0",df=True)
        symbol_list = df["symbol"].values
        _symbol_list = symbol_list
        symbol_list = []
        for _ in _symbol_list:
            symbol_list.append(_)


        """重要的获取标的的代码"""
        _symbol_list = my_own_fun.get_my_own_ago_3(symbol_list,now,target_index)
        """重要的获取标的的代码"""
        context.fun_name = "防守型策略_1"


        symbol_list = []
        for symbol in _symbol_list:
            if symbol not in context.black_list:#排除黑名单股票
                symbol_list.append(symbol)

        #取前多少个标的
        target_list = symbol_list[:context.num]


        # --------------市价单平不在标的池的
        positions = context.account().positions()
        # 如标的池有仓位,平不在标的池的股票仓位
        for position in positions:
            symbol = position['symbol']


            if (symbol not in target_list):
                order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,
                                     position_side=PositionSide_Long)
                context.symbol_high.pop(symbol)
                context.symbol_low.pop(symbol)



            #对还在股票池中的标的进行判断
            data = history_n(symbol,frequency="1d",count=1,end_time=now,fields="open",df=True)
            open = data["open"].values
            sell_flag = open[0] < context.symbol_high[symbol] * 0.93

            if sell_flag :
                order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,
                                     position_side=PositionSide_Long)
                context.black_list.append(symbol)
                context.symbol_high.pop(symbol)
                context.symbol_low.pop(symbol)

            elif context.symbol_high[symbol] > context.symbol_low[symbol] * 1.3:
                order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,
                                     position_side=PositionSide_Long)
                context.symbol_high.pop(symbol)
                context.symbol_low.pop(symbol)


        positions = context.account().positions()

        holded_symbol = []
        for position in positions:
            symbol = position['symbol']
            holded_symbol.append(symbol)

        for symbol in target_list:
            if (symbol not  in holded_symbol) and (symbol not in context.black_list):
                data = history_n(symbol, frequency="1d", count=2, end_time=now, fields="close,open", df=True)
                open = data["open"].values
                close = data["close"].values
                if open[-1] < close[0] * 1.08: #这里是对涨停板进行甄别,就用这个，用多少天的运算太慢
                    order_target_percent(symbol=symbol, percent=1. / context.num, order_type=OrderType_Market,
                                         position_side=PositionSide_Long)
                    context.symbol_high[symbol] = 0
                else:pass

def on_backtest_finished(context, indicator):
    print(indicator)
    res = [context.target_index, context.fun_name, indicator["sharp_ratio"], indicator["max_drawdown"], indicator["pnl_ratio"],
           indicator]
    writer = csv.writer(open(context.record_file, 'a+', encoding='utf8', newline=''))
    writer.writerow(res)

if __name__ == "__main__":
    run(
        strategy_id='4d370a96-0721-11e8-a4f0-2c56dc7b945c',
        filename=(os.path.basename(__file__)),
        mode=MODE_BACKTEST,
        token='a71a8083b68e73817e93f7f196b030482abe5939',
        backtest_start_time='2016-01-01 09:00:00',
        backtest_end_time='2018-05-31 15:00:00',
        backtest_initial_cash=10000000,
        backtest_adjust=ADJUST_PREV
    )
